package com.chenailin.www.controller.auth;

import com.chenailin.www.exception.BusinessException;
import com.chenailin.www.model.dto.LoginDTO;
import com.chenailin.www.model.dto.RegisterDTO;
import com.chenailin.www.model.pojo.User;
import com.chenailin.www.model.vo.ResultVO;
import com.chenailin.www.model.vo.UserVO;
import com.chenailin.www.service.AuthService;
import com.chenailin.www.service.VerificationCodeService;
import com.chenailin.www.serviceimpl.AuthServiceImpl;
import com.chenailin.www.serviceimpl.VerificationCodeServiceImpl;
import com.chenailin.www.util.JsonUtil;
import com.fasterxml.jackson.core.JsonParseException;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;

/**
 * @author evi
 */
@WebServlet("/*")
public class AuthController extends HttpServlet {
    private static final String BASE_PATH = "";
    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    // 使用依赖注入替代直接实例化
    private AuthService authService;

    // 声明 VerificationCodeService 成员变量，避免重复实例化
    private VerificationCodeService verificationCodeService;

    @Override
    public void init() throws ServletException {
        System.out.println("AuthController 初始化成功，映射路径：/Cloud/*");
        this.authService = new AuthServiceImpl();
        // 初始化 VerificationCodeService
        this.verificationCodeService = new VerificationCodeServiceImpl();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=UTF-8");
        String path = req.getRequestURI().substring(req.getContextPath().length());
        // 检查请求是否已经被处理过，避免无限循环
//        if (req.getAttribute("alreadyProcessed") != null) {
//            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "请求处理循环错误");
//            return;
//        }
//        // 标记请求已经被处理
//        req.setAttribute("alreadyProcessed", true);
//
//        String path = getNormalizedPath(req);
        if (path.endsWith(".html")) {
            // 考虑上下文路径
            String contextPath = req.getContextPath();
            String forwardPath = contextPath + path;
            logger.info("尝试转发到路径: {}", forwardPath);

            try {
                // 获取默认的 RequestDispatcher
                javax.servlet.RequestDispatcher dispatcher = req.getServletContext().getNamedDispatcher("default");
                if (dispatcher != null) {
                    // 直接使用 RequestDispatcher 进行转发
                    dispatcher.forward(req, resp);
                } else {
                    logger.error("默认 RequestDispatcher 未找到");
                    sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "默认 RequestDispatcher 未找到");
                }
            } catch (Exception e) {
                logger.error("请求转发出错，路径: {}, 错误信息: {}", forwardPath, e.getMessage(), e);
                sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "请求转发出错");
            }
        } else {
            sendError(resp, HttpServletResponse.SC_NOT_FOUND, "接口不存在");
        }

        try {
            if ("/register".equals(path)) {
                handleRegister(req, resp);
            }
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(400, "Invalid ID format")));
        } catch (Exception e) {
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.getWriter().write(JsonUtil.toJson(ResultVO.error(500, e.getMessage())));
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 统一设置响应头
        resp.setContentType("application/json;charset=UTF-8");
        resp.setHeader("X-Content-Type-Options", "nosniff");

        try {
            // 2. 获取规范化路径（如 /Cloud/email-code）
            String path = getNormalizedPath(req);
            try (BufferedWriter writer = new BufferedWriter(new FileWriter("/D:/code/cat/Cloud/email_log.txt", true))) {
                writer.write("路径: " +path+"\n");
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            // 3. 路由处理
            if ("/login".equals(path)) {
                handleLogin(req, resp);
            } else if ("/register".equals(path)) {
                handleRegister(req, resp);
            } else if ("/email-code".equals(path)) {
                handleSendRegisterCode(req, resp);
            } else if ("/check-username".equals(path)) {
                handleCheckUsername(req, resp);
            } else if ("/getuserinfo".equals(path)) {
                System.out.println("111");
                handleGetUserInfo(req, resp);
            } else {
                sendError(resp, HttpServletResponse.SC_NOT_FOUND, "接口不存在");
            }

        } catch (JsonParseException e) {
            logger.warn("JSON解析失败", e);
            sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "请求数据格式错误");
        } catch (BusinessException e) {
            logger.error("业务异常", e);
            sendJsonResponse(resp, ResultVO.error(e.getMessage()));
        } catch (Exception e) {
            logger.error("系统异常", e);
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "系统繁忙");
        }
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("=== 进入service方法 ===");
//        System.out.println("请求方法: " + req.getMethod());
        super.service(req, resp);
    }

    //=== 核心处理方法 ===//
    private void handleLogin(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try {
            // 1. 解析请求体并记录日志
            LoginDTO loginDTO = parseRequestBody(req, LoginDTO.class);
            System.out.println("接收到登录请求，数据: {}"+ loginDTO);

            // 2. 验证 DTO
            validateLoginDTO(loginDTO);

            // 4. 执行登录
            User user = authService.login(loginDTO, req);

            // 5. 创建会话
            createUserSession(req, user);

            // 6. 返回响应
            sendJsonResponse(resp, ResultVO.success(convertToUserVO(user)));
            logger.info("用户 {} 登录成功", loginDTO.getUsername());

        } catch (BusinessException e) {
//            System.out.println("【ERROR】登录处理异常: " + e.getMessage());
            logger.error("登录业务异常: {}", e.getMessage(), e);
            sendJsonResponse(resp, ResultVO.error(e.getMessage()));
        } catch (Exception e) {
            System.out.println("【ERROR】登录处理异常: " + e.getMessage());
            logger.error("登录系统异常: {}", e.getMessage(), e);
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "系统繁忙");
        }
    }

    private void handleRegister(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        try {
            RegisterDTO registerDTO = parseRequestBody(req, RegisterDTO.class);

            // 添加日志记录接收到的数据
            System.out.println("接收到注册请求，数据: {}" + registerDTO);

            // 验证DTO
            authService.validateRegisterDTO(registerDTO);

            // 验证邮箱验证码
            if (!verificationCodeService.validateCode(registerDTO.getEmail(), registerDTO.getEmailCode())) {
                sendError(resp, 400, "邮箱验证码错误或已过期");
                return;
            }
            // 执行注册
            authService.register(registerDTO, req);
            // 注册成功后返回响应
            sendJsonResponse(resp, ResultVO.success("注册成功"));

        } catch (BusinessException e) {
            logger.error("注册业务异常: {}", e.getMessage(), e);
            sendJsonResponse(resp, ResultVO.error(e.getMessage()));
        } catch (Exception e) {
            logger.error("注册系统异常: {}", e.getMessage(), e);
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "系统繁忙");
        }
    }

    /**
     * 处理发送注册验证码请求
     */
    private void handleSendRegisterCode(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1. 从请求体解析 JSON
        try (BufferedReader reader = req.getReader()) {
            String requestBody = IOUtils.toString(reader);
            Map<String, String> params = JsonUtil.fromJson(requestBody, Map.class);
            String email = params.get("email");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter("/D:/code/cat/Cloud/email_log.txt", true))) {
                writer.write("获取到的邮箱地址111: " + email + "\n");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
//            System.out.println("邮箱" + email);
            logger.info("获取到的邮箱地址: {}", email);
            if (email == null || email.isEmpty()) {
                sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "邮箱不能为空");
                return;
            }

            logger.info("开始发送验证码到邮箱: {}", email);
            // 2. 发送验证码
            try (BufferedWriter writer = new BufferedWriter(new FileWriter("/D:/code/cat/Cloud/email_log.txt", true))) {
                writer.write("验证码已存储，邮箱authcontroller: " + email + ", 验证码: " + "\n");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            verificationCodeService.sendVerificationCode(email);
            sendJsonResponse(resp, ResultVO.success("验证码发送成功"));
            logger.info("成功发送验证码到邮箱: {}", email);
        } catch (BusinessException e) {
            logger.error("发送验证码时业务异常: {}", e.getMessage(), e);
            sendJsonResponse(resp, ResultVO.error(e.getMessage()));
        } catch (IOException e) {
            logger.error("读取请求体或发送响应时出现 I/O 异常: {}", e.getMessage(), e);
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "读取或发送数据时出错");
        } catch (Exception e) {
            logger.error("发送验证码时出现未知异常: {}", e.getMessage(), e);
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "系统繁忙");
        }
    }

    /**
     * 处理用户名检查请求
     */
    private void handleCheckUsername(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1. 获取用户名参数
        String username = req.getParameter("username");

        // 2. 验证参数
        if (username == null || username.trim().isEmpty()) {
            sendJsonResponse(resp, ResultVO.error("用户名不能为空"));
            return;
        }

        if (username.length() < 4) {
            sendJsonResponse(resp, ResultVO.error("用户名至少需要4个字符"));
            return;
        }

        // 3. 这里假设你有对应的userService实例，若没有，需先实例化
        // 检查用户名是否可用
        try {
            boolean isAvailable = authService.isUsernameAvailable(username);
            if (isAvailable) {
                sendJsonResponse(resp, ResultVO.success("用户名可用"));
            } else {
                sendJsonResponse(resp, ResultVO.error("用户名已被占用"));
            }
        } catch (Exception e) {
            logger.error("检查用户名时出错", e);
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "检查用户名失败");
        }
    }

    private void handleGetUserInfo(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("currentUser");
        System.out.println(user.getPassword());
        if (user != null) {
            UserVO userVO = convertToUserVO(user);
            sendJsonResponse(resp, ResultVO.success(userVO));
        } else {
            sendError(resp, HttpServletResponse.SC_UNAUTHORIZED, "用户未登录");
        }
    }
    //    private void handleCheckUsername(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    //        String username = req.getParameter("username");
    //        if (username == null || username.isEmpty()) {
    //            sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "用户名不能为空");
    //            return;
    //        }
    //        boolean isAvailable = authService.checkUsernameAvailable(username);
    //        sendJsonResponse(resp, ResultVO.success(isAvailable));
    //    }
    //
    //    private void handleCaptcha(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    //        // 生成验证码的逻辑
    //        String captcha = authService.generateCaptcha();
    //        String token = UUID.randomUUID().toString();
    //        // 存储 token 和验证码的关系（如 Redis 或 Session）
    //        sendJsonResponse(resp, ResultVO.success(Map.of("image", captchaImage, "token", token)));
    //    }

    //=== 工具方法 ===//
    private String getNormalizedPath(HttpServletRequest req) {
        String path = req.getRequestURI().substring(req.getContextPath().length());
        System.out.println("规范化路径: " + path);
        return path.replaceAll("/{2,}", "/").toLowerCase();
    }

    private <T> T parseRequestBody(HttpServletRequest req, Class<T> clazz) throws IOException {
        try (BufferedReader reader = req.getReader()) {
            return JsonUtil.fromJson(IOUtils.toString(reader), clazz);
        }
    }

    private void validateLoginDTO(LoginDTO dto) throws BusinessException {
        if (dto.getUsername().isEmpty() || dto.getPassword().isEmpty()) {
            throw new BusinessException("用户名不能为空");
        }
        // 其他校验规则...
    }

    private void createUserSession(HttpServletRequest req, User user) {
        HttpSession session = req.getSession();
        session.setAttribute("currentUser", user);
        session.setAttribute("username", user.getUsername());
        session.setAttribute("email", user.getEmail());
        session.setAttribute("password", user.getPassword());
        session.setAttribute("avatar", user.getAvatar());
        session.setAttribute("userId", user.getId());
        // 假设在登录成功后

        // 安全设置 // 30分钟过期
        session.setMaxInactiveInterval(30 * 60);
    }

    private UserVO convertToUserVO(User user) {
        UserVO vo = new UserVO();
        vo.setId(user.getId());
        vo.setUsername(user.getUsername());
        vo.setPassword(user.getPassword());
        vo.setAvatar(user.getAvatar());
        // 注意：不返回敏感字段
        return vo;
    }

    //=== 响应方法 ===//
    private void sendJsonResponse(HttpServletResponse resp, ResultVO<?> result) throws IOException {
        resp.getWriter().write(JsonUtil.toJson(result));
    }

    private void sendError(HttpServletResponse resp, int code, String message) throws IOException {
        resp.setStatus(code);
        resp.setContentType("application/json;charset=UTF-8");
        ResultVO<?> result = ResultVO.error(message);
        resp.getWriter().write(JsonUtil.toJson(result));
    }

    @Override
    public void destroy() {
        // 清理资源
    }
}